from mirror import LookingGlass
from mirror_gen import looking_glass
# 上下文管理器和else块

# 1、先做这个，再做那个：if语句之外的else块
# for 仅当 for 循环运行完毕时（即 for 循环没有被 break 语句中止）才运行 else 块
# while 仅当 while 循环因为条件为假值而退出时（即 while 循环没有被 break 语句中止）才运行 else 块
# try 仅当 try 块中没有异常抛出时才运行 else 块
# 在所有情况下，如果异常或者 return、break 或 continue 语句导致控制权跳到了复合语句的主块之外，else 子句也会被跳过

# 2、上下文管理器和with块
# 简化try/finally模式
# 上下文管理器协议包含 __enter__ 和 __exit__ 两个方法
# with 语句开始运行时，会在上下文管理器对象上调用 __enter__ 方法
# with 语句运行结束后，会在上下文管理器对象上调用 __exit__ 方法

# 执行with 后面的表达式得到的结果是上下文管理器对象，不过，把值绑定
# 到目标变量上（as 子句）是在上下文管理器对象上调用 __enter__ 方法的结果
with open('mirror.py', encoding='utf8') as fp:
    src = fp.read(60)

print(len(src))
print(fp)
print(fp.closed, fp.encoding)
# ValueError: I/O operation on closed file.
# print(fp.read(60))

with LookingGlass() as what:
    print('Alice,Kitty and Snowdrop')
    print(what)

print(what)
print('Back to normal')
# 上下文管理具体工作方式
manager = LookingGlass()
print(manager)
monster = manager.__enter__()
print(monster == 'JABBERWOCKY')
print(monster)
print(manager)
manager.__exit__(None, None, None)
print(monster)

# 3、contextlib模块中的实用工具
# ...
# 4、使用@contextmanager
# yield 语句前面的所有代码在 with 块开始时（即解释器调用 __enter__ 方法时）执行， yield 语句后面的代码在 with 块结束时（即调用 __exit__ 方法时）执行
print("---@contextmanager---")
with looking_glass() as what:
    print('Alice,Kitty and Snowdrop')
    print(what)
print(what)